#include "HelloWorldScene.h"

USING_NS_CC;
using namespace ui;
Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
	auto scene = Scene::create();

	// 'layer' is an autorelease object
	auto layer = HelloWorld::create();

	// add layer as a child to scene
	scene->addChild(layer);

	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
	//////////////////////////////
	// 1. super init first
	if ( !Layer::init() )
	{
		return false;
	}

	
	// 初始化物理引擎
	this->initPhysics();

	setTouchEnabled(true);
	//设置为单点触摸
	setTouchMode(Touch::DispatchMode::ONE_BY_ONE);

	Size s = Director::getInstance()->getVisibleSize();
	
	auto bgsprite1 = Sprite::create("res/tiesuo.png");
	bgsprite1->setScale(s.width / 900);
	bgsprite1->setPosition(Point(s.width / 2, s.height / 2));
	this->addChild(bgsprite1, -2);

	//返回按钮
	heBack = Button::create();
	heBack->setTouchEnabled(true);
	heBack->loadTextures("res/return.png", "res/return.png", "");
	heBack->setScale(s.width / 900);
	heBack->setPosition(Point(s.width / 12, s.height*23 / 24));
	heBack->addTouchEventListener(this, toucheventselector(HelloWorld::heBacktouchEvent));
	this->addChild(heBack,0);

	yuan = Sprite::create("res/yuan.png");
	yuan->setScale(s.width / 900);
	yuan->setPosition(Point(s.width / 2, 0));
	this->addChild(yuan, -5);
	mid = Sprite::create("res/mground.png");
	mid->setScale(s.width / 900);
	mid->setPosition(Point(s.width / 2, -s.height * 0.5));
	this->addChild(mid, -4);
	jin = Sprite::create("res/jin.png");
	jin->setScale(s.width / 900);
	jin->setPosition(Point(s.width / 2, -s.height));
	this->addChild(jin, -3);
	vg = 0.25 * s.width / 900;;     //初始化滚动速度

	//注册捕捉监听  
	auto listenerkeyPad = EventListenerKeyboard::create();
	listenerkeyPad->onKeyReleased = CC_CALLBACK_2(HelloWorld::onKeyReleased, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listenerkeyPad, this);
	//初始化方向
	left = false;
	right = false;
	drop = false;
	
	//音乐
	//加载音乐
	CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic("res/gamingM.mp3");
	//设置默认音量
	CocosDenshion::SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(50);
	//播放背景音乐
	CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("res/gamingM.mp3", true);
	//加载音乐
	
	CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect("res/collision.ogg");
	//加载音乐
	CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect("res/playerdead.ogg");

	initScore();
	initGold();
	//开始游戏循环
	scheduleUpdate();

	return true;
}

//初始化分数
void HelloWorld::initScore()
{
	Size s = Director::getInstance()->getVisibleSize();
	fenshu = 0;
	for (int i = 0; i < 5 ; i++)
	{
		score[i] = Sprite::create("res/score.png", Rect( 0, 0, 40, 40));
		score[i]->setScale(s.width / 900);
		score[i]->setPosition(Point(s.width/2-125 * s.width / 900 + 50 * i*s.width / 900 + score[i]->getBoundingBox().size.width / 2, s.height*23 / 24));
		this->addChild(score[i],0);
	}
}

//初始化物理引擎
void HelloWorld::initPhysics()
{
	Size s = Director::getInstance()->getVisibleSize();

	

	
	//重力参数
	b2Vec2 gravity;
	gravity.Set(0.0f, -10.0f);
	//创建世界
	world = new b2World(gravity);
	// 允许物体是否休眠
	world->SetAllowSleeping(true);
	// 开启连续物理测试
	world->SetContinuousPhysics(true);

	/*debugDraw = new GLESDebugDraw(PTM_RATIO);
	uint32 flags = 0;
	flags += b2Draw::e_shapeBit;
	//flags += b2Draw::e_jointBit; 
	//flags += b2Draw::e_aabbBit; 
	//flags += b2Draw::e_pairBit; 
	//flags += b2Draw::e_centerOfMassBit;
	debugDraw->SetFlags(flags);
	world->SetDebugDraw(debugDraw);*/
	

	// 定义物体地面
	b2BodyDef groundBodyDef;
	groundBodyDef.position.Set(0, 0);

	//创建地面物体
	b2Body* groundBody = world->CreateBody(&groundBodyDef);

	//定义一个有边的形状
	b2EdgeShape groundBox;

	// 底部
	//groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO-10,0));
	//使用夹具固定形状到物体上
	//groundBody->CreateFixture(&groundBox,0);

	// 顶部
	//groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));
	//groundBody->CreateFixture(&groundBox,0);

	// 左边
	//groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));
	//groundBody->CreateFixture(&groundBox,0);

	// 右边
	//groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0));
	//groundBody->CreateFixture(&groundBox,0);

	addNewSpriteAtPosition(Vec2(s.width / 2, s.height / 4));
	addNewSprite(Vec2(s.width / 2, s.height / 4 + (float)s.width * 96 / 900));
	//log("%f,%f", s.width / 2, s.height / 4);
	float num = random(0, 1);
	if (num>=0.5)
	{
		player->ApplyForceToCenter(b2Vec2(10 * s.width / 900 * s.width / 900, 0), true);
	}
	else
	{
		player->ApplyForceToCenter(b2Vec2(-10 * s.width / 900 * s.width / 900, 0), true);
	}
	

}
//调试绘制
void HelloWorld::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4& transform, uint32_t flags)
{
	//world->DrawDebugData();
}
void HelloWorld::onKeyReleased(cocos2d::EventKeyboard::KeyCode keycode, cocos2d::Event* event)
{
	switch (keycode)
	{
	case cocos2d::EventKeyboard::KeyCode::KEY_BACK:   //返回键听
		Director::getInstance()->replaceScene(TransitionFade::create(1.2f, StartScene::createScene()));
		break;
	case cocos2d::EventKeyboard::KeyCode::KEY_MENU:      //菜单监听
		//Director::getInstance()->replaceScene(TransitionFade::create(1.2f, StartScene::createScene()));
		break;
	case cocos2d::EventKeyboard::KeyCode::KEY_HOME:
		//Director::getInstance()->replaceScene(TransitionFade::create(1.2f, StartScene::createScene()));
		break;
	default:
		break;
	}
}
void HelloWorld::heBacktouchEvent(cocos2d::Object *pSender, cocos2d::ui::TouchEventType type)
{
	Button* butten = (Button*)pSender;
	unsigned int tag = butten->getTag();
	switch (type)
	{
	case ui::TOUCH_EVENT_BEGAN:
		butten->setPositionY(butten->getPositionY() - 10);
		break;

	case ui::TOUCH_EVENT_MOVED:

		break;

	case ui::TOUCH_EVENT_ENDED:
		butten->setPositionY(butten->getPositionY() + 10);

		Director::getInstance()->replaceScene(TransitionFade::create(1.2f, StartScene::createScene()));


		break;

	case ui::TOUCH_EVENT_CANCELED:
		butten->setPositionY(butten->getPositionY() + 10);
		break;

	default:
		break;
	}
}
bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
{
	Size s = Director::getInstance()->getVisibleSize();
	Vec2 location = touch->getLocation();
	//addNewSprite(location);
	//log("%f,%f", location.x, location.y);
	//施加向左向右的力
	if (location.x > (s.width / 2))
	{
		right = true;
		
	}
	if (location.x < (s.width / 2))
	{
		left = true;
		
	}
	
	return false;
}
void HelloWorld::onTouchMoved(Touch* touch, Event* event)
{
	
}
void HelloWorld::onTouchEnded(Touch* touch, Event* event)
{
	right = false;
	left = false;
}
//产生随机数
int HelloWorld::productRandom(int start,int end)
{
	int num = end - start;
	int num2 = rand() % num + start;
	return num2;
}
void HelloWorld::initGold()
{
	Size s = Director::getInstance()->getVisibleSize();
	
	aLive = false;
	v = 2;
	distance = 150*s.height/1600;
	for (int i = 0; i < GOLD_NUM_MAX ; i++)
	{
		int rand = productRandom(s.width / 6, s.width * 5 / 6);
		auto Gold = Sprite::create("res/gold.png");
		Gold->setScale(s.width / 900);
		Gold->setPosition(Vec2(rand, s.height + distance * i));
		this->addChild(Gold,0);
		gold[i] = Gold;
		
	}
}
//产生玩家
void HelloWorld::addNewSprite(Vec2 p)
{
	Size s = Director::getInstance()->getVisibleSize();
	den = 0.15;
	spritePlayer = Sprite::create("res/Ball.png");
	spritePlayer->setScale(s.width / 900);
	spritePlayer->setPosition(p);
	spritePlayer->getTexture()->setAliasTexParameters();
	this->addChild(spritePlayer,1);

	// 动态物体A定义
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	bodyDef.position.Set(p.x / PTM_RATIO, p.y / PTM_RATIO);
	player = world->CreateBody(&bodyDef);
	player->SetUserData(spritePlayer);

	// 定义2米见方的盒子形状
	b2PolygonShape dynamicBox;
	dynamicBox.SetAsBox((float)s.width * 80 / 900 / PTM_RATIO, (float)s.height * 50/ 1600 / PTM_RATIO);

	// 动态物体夹具定义
	b2FixtureDef fixtureDef;   //玩家夹具
	//设置夹具的形状
	fixtureDef.shape = &dynamicBox;
	//设置密度
	fixtureDef.density = den;
	//设置摩擦系数
	fixtureDef.friction = 0.5f;

	//使用夹具固定形状到物体上
	player->CreateFixture(&fixtureDef);


}
void HelloWorld::addNewSpriteAtPosition(Vec2 p)
{    
	//log("Add sprite %0.2f x %02.f",p.x,p.y);
	Size s = Director::getInstance()->getVisibleSize();
	//创建物理引擎精灵对象A
	auto spriteA = Sprite::create("res/platform.png");
	spriteA->setScale(s.width / 900);
	spriteA->getTexture()->setAliasTexParameters();
	spriteA->setPosition(p);
	this->addChild(spriteA,1);


	// 动态物体A定义
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);
	b2Body *bodyA = world->CreateBody(&bodyDef);
	bodyA->SetUserData(spriteA);

	
	
	/*b2BodyDef bodyDefE;
	bodyDefE.type = b2_staticBody;
	bodyDefE.position.Set(p.x / PTM_RATIO + (float)s.width * 64 / 900 / PTM_RATIO, p.y / PTM_RATIO - (float)s.height * 200 / 1600 / PTM_RATIO);
	b2Body *bodyE = world->CreateBody(&bodyDefE);

	b2BodyDef bodyDefF;
	bodyDefF.type = b2_staticBody;
	bodyDefF.position.Set(p.x / PTM_RATIO - (float)s.width * 64 / 900 / PTM_RATIO, p.y / PTM_RATIO - (float)s.height * 200 / 1600 / PTM_RATIO);
	b2Body *bodyF = world->CreateBody(&bodyDefF);*/

	//创建物理引擎精灵对象B
	// 动态物体B定义
	bodyDef.type = b2_staticBody;
	bodyDef.position.Set(p.x / PTM_RATIO, p.y / PTM_RATIO - (float)s.height * 20 / 1600 / PTM_RATIO);
	b2Body *bodyB = world->CreateBody(&bodyDef);

	

	// 定义2米见方的盒子形状
	b2PolygonShape dynamicBoxA;
	dynamicBoxA.SetAsBox((float)s.width * 400 / 900 / PTM_RATIO, (float)s.height * 40 / 1600 / PTM_RATIO);

	// 定义2米见方的盒子形状
	b2PolygonShape dynamicBoxB;
	dynamicBoxB.SetAsBox(0, 0);

	b2PolygonShape dynamicBoxC;
	dynamicBoxC.SetAsBox((float)s.width * 16 / 900 / PTM_RATIO, (float)s.height * 16 / 1600 / PTM_RATIO);
	// 动态物体夹具定义
	b2FixtureDef fixtureDefA;
	//设置夹具的形状
	fixtureDefA.shape = &dynamicBoxA;
	//设置密度
	fixtureDefA.density = 0.35f;
	//设置摩擦系数
	fixtureDefA.friction = 0.6f;
	
	b2FixtureDef fixtureDefB;
	fixtureDefB.shape = &dynamicBoxB;
	//设置密度
	fixtureDefB.density = 0.3f;
	//设置摩擦系数
	fixtureDefB.friction = 1.0f;

	b2FixtureDef fixtureDefC;
	fixtureDefC.shape = &dynamicBoxC;
	//设置密度
	fixtureDefC.density = 1.0f;
	//设置摩擦系数
	fixtureDefC.friction = 0.3f;

	//使用夹具固定形状到物体上
	bodyA->CreateFixture(&fixtureDefA);
	bodyB->CreateFixture(&fixtureDefB);
	//bodyE->CreateFixture(&fixtureDefC);
	//bodyF->CreateFixture(&fixtureDefC);
	// 距离关节定义
	b2DistanceJointDef jointDef;
	jointDef.Initialize(bodyA, bodyB, bodyA->GetWorldCenter(),
		bodyB->GetWorldCenter());
	jointDef.collideConnected = true; 

	bodyA->GetWorld()->CreateJoint(&jointDef);


}
//碰撞检测
bool HelloWorld::collisionSprite(cocos2d::Sprite *a, cocos2d::Sprite *b)
{
	if (a->getBoundingBox().intersectsRect(b->getBoundingBox()))
	{
		return true;
	}
	return false;
}
//分数显示更新
void HelloWorld::scoreOut()
{
	if (fenshu<10)
	{
		score[4]->setTexture("res/score.png");
		score[4]->setTextureRect(Rect(fenshu*40,0,40,40));
	}
	if (fenshu>=10&&fenshu<100)
	{
		int s = fenshu / 10;
		int g = fenshu - s * 10;
		score[4]->setTexture("res/score.png");
		score[4]->setTextureRect(Rect(g * 40, 0, 40, 40));
		score[3]->setTexture("res/score.png");
		score[3]->setTextureRect(Rect(s * 40, 0, 40, 40));

	}
	if (fenshu >= 100 && fenshu<1000)
	{
		int q = fenshu / 100;
		int s = (fenshu - q * 100) / 10;
		int g = fenshu - q * 100 - s * 10;
		score[4]->setTexture("res/score.png");
		score[4]->setTextureRect(Rect(g * 40, 0, 40, 40));
		score[3]->setTexture("res/score.png");
		score[3]->setTextureRect(Rect(s * 40, 0, 40, 40));
		score[2]->setTexture("res/score.png");
		score[2]->setTextureRect(Rect(q * 40, 0, 40, 40));

	}
	if (fenshu >= 1000 && fenshu < 10000)
	{
		int w = fenshu / 1000;
		int q = (fenshu - w * 1000) / 100;
		int s = (fenshu - w * 1000 - q * 100) / 10;
		int g = fenshu -w*1000 - q * 100 - s * 10;
		score[4]->setTexture("res/score.png");
		score[4]->setTextureRect(Rect(g * 40, 0, 40, 40));
		score[3]->setTexture("res/score.png");
		score[3]->setTextureRect(Rect(s * 40, 0, 40, 40));
		score[2]->setTexture("res/score.png");
		score[2]->setTextureRect(Rect(q * 40, 0, 40, 40));
		score[1]->setTexture("res/score.png");
		score[1]->setTextureRect(Rect(w * 40, 0, 40, 40));

	}
	if (fenshu >= 10000 && fenshu < 100000)
	{
		int sw = fenshu / 10000;
		int w = (fenshu - sw*10000) / 1000;
		int q = (fenshu - sw * 10000 - w * 1000) / 100;
		int s = (fenshu - sw * 10000 - w * 1000 - q * 100) / 10;
		int g = fenshu - sw * 10000 - w * 1000 - q * 100 - s * 10;
		score[4]->setTexture("res/score.png");
		score[4]->setTextureRect(Rect(g * 40, 0, 40, 40));
		score[3]->setTexture("res/score.png");
		score[3]->setTextureRect(Rect(s * 40, 0, 40, 40));
		score[2]->setTexture("res/score.png");
		score[2]->setTextureRect(Rect(q * 40, 0, 40, 40));
		score[1]->setTexture("res/score.png");
		score[1]->setTextureRect(Rect(w * 40, 0, 40, 40));
		score[0]->setTexture("res/score.png");
		score[0]->setTextureRect(Rect(sw * 40, 0, 40, 40));

	}
}
void HelloWorld::transf(float dt)
{
	Scene* scene = Scene::create();
	EndScene *layer = EndScene::create();
	layer->score = fenshu;
	scene->addChild(layer);//类似firstScene中的scene()方法  
	
	
	Director::getInstance()->replaceScene(TransitionFade::create(1.2f, scene));
}
//游戏循环
void HelloWorld::update(float dt)
{
	Size s = Director::getInstance()->getVisibleSize();
	float timeStep = 0.03f; 
	int32 velocityIterations = 8;	
	int32 positionIterations = 1;	

	world->Step(timeStep, velocityIterations, positionIterations);

	for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
	{
		if (b->GetUserData() != nullptr) {									
			Sprite* sprite = (Sprite*)b->GetUserData();	
			sprite->setPosition( Vec2( b->GetPosition().x * 
				PTM_RATIO, b->GetPosition().y * PTM_RATIO) );	
			sprite->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );
		}
	}

	scoreOut();

	for (int i = 0; i < GOLD_NUM_MAX ; i++)
	{
		pos = gold[i]->getPositionY();
		pos -= v*s.height/1600;
		gold[i]->setPositionY(pos);
		
		if (collisionSprite(spritePlayer,gold[i]))
		{
			if (!aLive)
			{
				aLive = true;
				fenshu++;
				den += 0.01;
				player->GetFixtureList()->SetDensity(den);
				//音乐
				
				//设置默认音量
				CocosDenshion::SimpleAudioEngine::sharedEngine()->setEffectsVolume(50);
				//播放背景音乐
				CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("res/collision.ogg", false);
			}
			gold[i]->setVisible(false);
			
		}
		if (gold[i]->getPositionY()<0)
		{
			windo = Director::getInstance()->getVisibleSize();
			ran = productRandom(windo.width / 6, windo.width * 5 / 6);
			gold[i]->setPosition(Vec2(ran, windo.height));
			gold[i]->setVisible(true);
			
			aLive = false;
		}
	}
	if (drop==false)
	{
		if (spritePlayer->getPositionY() < 0)
		{
			drop = true;

		}
	}
	
	if (drop)
	{
		scheduleOnce(schedule_selector(HelloWorld::playE), 0.1f); //在1.0f之后执行，并且只执行一次
		scheduleOnce(schedule_selector(HelloWorld::transf), 1.5f); //在1.0f之后执行，并且只执行一次
		
		drop = false;
	}

	//施加力
	if (right)
	{
		player->ApplyForceToCenter(b2Vec2(250 * s.width / 900 * s.width / 900, 0), true);
		right = false;
	}
	if (left)
	{
		player->ApplyForceToCenter(b2Vec2(-250 * s.width / 900 * s.width / 900, 0), true);
		left = false;
	}

	//背景滚动
	ji = jin->getPositionY();
	ji += 3 * vg;
	jin->setPositionY(ji);
	mi = mid->getPositionY();
	mi += 2 * vg;
	mid->setPositionY(mi);
	yu = yuan->getPositionY();
	yu += vg;
	yuan->setPositionY(yu);
	if (jin->getPositionY() >= s.height * 2)
	{
		vg = 0;
	}
	
}
void HelloWorld::playE(float dt)
{

	//音乐
	CocosDenshion::SimpleAudioEngine::sharedEngine()->stopAllEffects();
	//设置默认音量
	CocosDenshion::SimpleAudioEngine::sharedEngine()->setEffectsVolume(50);
	//播放背景音乐
	CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("res/playerdead.ogg", false);
}

HelloWorld::~HelloWorld()
{
	CC_SAFE_DELETE(world);    
}
